#include "cookie.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "xmalloc.h"


static cookie_obj_t *
new_cookie(char *key, char *value);

__inline__ ck_map_t
parse_cookies(dict_t *http_hdr)
{
  char *tmp, *key, *val, *saveptr1, *saveptr2, *ck;
  const char *s_cookie = lookup(http_hdr, "Cookie");
  ck_map_t m = cookie_map_new();
  cookie_obj_t *c;

  if (s_cookie) {
    ck = strndup(s_cookie, COOKIE_MAX_LEN);
    tmp = strtok_r( (char *)ck, ";", &saveptr1);
    do {
      if (tmp[0] == ' ') tmp++;
      key = tmp;
      if ((key = strtok_r(key, "=", &saveptr2))) {
        if ((val = strtok_r(NULL, "=", &saveptr2))) {
          c = new_cookie(key, val);
          cookie_map_put(m, c->key, c);
        }
      }
    } while ( (tmp = strtok_r(NULL, ";", &saveptr1)) );
    free(ck);
  }
  return (m);
}

__inline__ static cookie_obj_t *
last_cookie_obj(ck_map_t *m, char *key)
{
  cookie_obj_t *tmp;

  if (m == NULL) return (NULL);
  if (cookie_map_get(m, key, &tmp) != COOKIE_OK) return (NULL);
  while (tmp != NULL) {
    tmp = tmp->next;
  }
  return (tmp);
}

__inline__ static cookie_obj_t *
new_cookie(char *key, char *value)
{
  cookie_obj_t *obj = ncmalloc(1, sizeof(struct cookie_obj));

  assert(obj != NULL);
  if (obj == NULL) return (NULL);
  obj->key = strndup(key, COOKIE_MAX_KEYLEN);
  obj->val = strndup(value, COOKIE_MAX_VALLEN);
  assert(obj->val != NULL);
  obj->next = NULL;
  return (obj);
}

__inline__ void
insert_cookie(ck_map_t m, char *key, char *value)
{
  cookie_obj_t *obj = NULL;

  switch (cookie_map_get(m, key, &obj))
  {
    case COOKIE_OK:
      obj = last_cookie_obj(m, key);
    case COOKIE_MIS:
      if ( (obj = new_cookie(key, value)) != NULL ) {
        if (cookie_map_put(m, key, obj) != COOKIE_OK) {
        }
      }
      break;
    case COOKIE_FULL:
    case COOKIE_OMEM:
      break;
  }
}

__inline__ void
cookie_free(ck_map_t m)
{
  int i = 0;
  cookie_obj_t *obj = NULL;

  while (cookie_iterate(m, &i, NULL, &obj) == true) {
    if (obj) {
      free(obj->key);
      free(obj->val);
      ncfree(obj, sizeof(struct cookie_obj));
    }
  }
}

